package com.wumz.spring.write.v2.framework.aop.proxy;

import com.wumz.spring.write.v2.framework.aop.aspect.MyAdvice;
import com.wumz.spring.write.v2.framework.aop.support.MyAdvisedSupport;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Map;

/**
 * Created by wumz on 2020/10/1 21:51
 */
public class MyJdkDynamicAopProxy implements InvocationHandler {

    private MyAdvisedSupport config;

    public MyJdkDynamicAopProxy(MyAdvisedSupport config) {
        this.config = config;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        //根据一个目标代理类的方法，获得其对应的通知
        Map<String,MyAdvice> advices = config.getAdvices(method);
        Object returnValue = null;
        try {
            invokeAdivce(advices.get("before"));
            returnValue = method.invoke(this.config.getTarget(), args);
            invokeAdivce(advices.get("after"));
        }catch (Exception e){
            invokeAdivce(advices.get("afterThrow"));
        }
        return returnValue;
    }

    /**
     * 根据一个目标代理类的方法，获得其对应的通知
     * @param advice
     */
    private void invokeAdivce(MyAdvice advice) {
        try {
            advice.getAdviceMethod().invoke(advice.getAspect());
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
    }

    public Object getProxy() {
        return Proxy.newProxyInstance(this.getClass().getClassLoader(),this.config.getTargetClass().getInterfaces(),this);
    }
}
